package com.beiding.service.email;

import com.beiding.dao.KeyValueDao;
import com.beiding.exception.BadRequestException;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

@Aspect
@Component
public class EmailAspect {


    private KeyValueDao keyValueDao;

    @Autowired
    public void setKeyValueDao(KeyValueDao keyValueDao) {
        this.keyValueDao = keyValueDao;
    }

    //发送邮件时间限定

    //对于非系统性的发邮件请求(发送验证码,发送找回密码邮件,发送申请权限请求),限定一分钟

    @Before(value = "execution(* com.beiding.service.email.EmailService.sendCode(..))&&args(email)||execution(* com.beiding.service.email.EmailService.sendRetrievePassword(..))&&args(email,..)||execution(* com.beiding.service.email.EmailService.sendApplyForManager(..))&&args(email,..)")
    public void PreSend(String email) {



        //为了防止恶意攻击造成邮件服务假死.对客户端ip地址进行限制


        String ip = ip();

        String ipKey = ip + "email_time_limit";

        //限制一定的次数.在半个小时内发送邮件的次数不能多于10次
        Integer time = (Integer) keyValueDao.get(ipKey);

        if (time == null) {
            keyValueDao.put(ipKey, 1, 1800);
        }else if (time > 10) {
            throw new BadRequestException("由于您的ip请求邮件次数过多已被暂时限制");
        } else {
            //更新key
            keyValueDao.put(ipKey, time + 1, 1800);
        }


        String key = email + "_time_limit";
        String f = (String) keyValueDao.get(key);

        //数据库中如果含有该邮件对应的锁就禁止发送
        if (f != null) {
            throw new BadRequestException("邮件发送频率过高,请稍后");
        } else {

            //添加添加标记位
            keyValueDao.put(key, "Lock", 58);
        }


    }


    private String ip() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes()).getRequest();

        //客户端可以伪造x-forwarded-for请求头

        //本项目由于并未采取nginx等反向代理技术,所以认为x-forwarded-for中并不包含反向代理的ip,因此认为x-forwarded-for请求头右侧第一个即为实际用户ip地址

        String ff = request.getHeader("x-forwarded-for");

        String[] strings = ff.split(",");

        return strings[strings.length - 1];

    }


}
